package com.zx.zxapibackend.utils;

import cn.hutool.core.util.BooleanUtil;
import com.zx.zxapibackend.common.RedisTokenBucket;
import com.zx.zxapicommon.constant.RedisConstant;
import com.zx.zxapicommon.model.dto.SmsDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @author 张旭
 * @version 1.0
 */
@Component
@Slf4j
public class SmsUtils {

    @Autowired
    private RedisTemplate redisTemplate;

    @Resource
    private RedisTokenBucket redisTokenBucket;

    @Resource
    private SmsRabbitmqUtils rabbitmqUtils;

    /**
     * 1.限流
     * 2.将code存入redis中
     * 3.mq消费消息
     * 4.调用第三方发送短信
     *
     * @param smsDTO
     * @return
     */
    public Boolean sendSms(SmsDTO smsDTO) {

        //从令牌桶中获取令牌
        Boolean acquire = redisTokenBucket.tryAcquire(smsDTO.getPhoneNum());

        //未获取到令牌，不允许发短信
        if (BooleanUtil.isFalse(acquire)) {
            log.info("phoneNumber:{},send SMS frequent", smsDTO.getPhoneNum());
            return false;
        }

        log.info("发送短信：{}", smsDTO);
        String phoneNum = smsDTO.getPhoneNum();
        String code = smsDTO.getCode();

        //将手机号对应的验证码存入redis，方便后于检验,过期时间5分钟
        redisTemplate.opsForValue().set(RedisConstant.SMS_CODE_PREFIX + phoneNum, code, 5, TimeUnit.MINUTES);

        //利用消息队列，异步发送短信
        rabbitmqUtils.sendSmsAsync(smsDTO);
        return true;
    }

    /**
     * 验证手机号对应的验证码是否一致
     *
     * @param phoneNum
     * @param code
     * @return
     */
    public boolean verifyCode(String phoneNum, String code) {
        String key = RedisConstant.SMS_CODE_PREFIX + phoneNum;
        String redisCode = String.valueOf(redisTemplate.opsForValue().get(key));
        if (null != code && redisCode.equals(code)) {
            redisTemplate.delete(key);
            return true;
        }
        return false;
    }

}
